from coin.exchange.base.order_gateway import OrderType
from coin.exchange.binance.kr_rest.product import BinanceProduct
from coin.exchange.binance.order_gateway import BinanceOrderGateway
from coin.strategy.executor.aggressive.aggressive_executor import AggressiveExecutor
from coin.strategy.executor.passive.simple_mm_executor import \
  SimpleMMExecutor
from coin.strategy.executor.util.traits import (order_logger, SpotExecutorTraits)
from coin.proto.coin_executor_pb2 import PASSIVE_EXECUTOR


class BinanceSimpleTraits(SpotExecutorTraits):
  @order_logger
  def _submit_order(self, product, price, qty, order_side):
    if not self.og.submittable():
      self._logger.warn('Skip submission: %s %f@%f' % (product, qty, price))
      return False

    self.og.submit(product, price, qty, order_side, OrderType.LIMIT)

  @order_logger
  def _submit_pass_order(self, product, price, qty, order_side):
    if not self.og.submittable():
      self._logger.warn('Skip submission: %s %f@%f' % (product, qty, price))
      return False

    assert self._executor_type == PASSIVE_EXECUTOR
    self.og.submit(product,
                   price,
                   qty,
                   order_side,
                   OrderType.LIMIT,
                   post_only=self.config.post_only)

  def _cancel_orders_impl(self, order_id_list):
    self.og.cancel_multiple(order_id_list)


class BinanceSimpleMMExecutor(SimpleMMExecutor):
  ProductType = BinanceProduct
  OGType = BinanceOrderGateway
  Traits = BinanceSimpleTraits


class BinanceSimpleAggExecutor(AggressiveExecutor):
  ProductType = BinanceProduct
  OGType = BinanceOrderGateway
  Traits = BinanceSimpleTraits
